<?php
/**
 * 每月计算数据
 */
apf_require_class('Oa_Job_Abstract');

class Oa_Job_Report_SumMonthReport extends Oa_Job_Abstract {

    private $write_db = "hroa_master";//读数据库
    private $datalist = array();

    public function run($params) {
        $time_start = time();
        $type = empty($params['type'])? '' : $params['type'];//设定更新哪一步
        $dep_id = empty($params['dep_id'])? 0 : $params['dep_id'];//设定更新哪一步

        if($dep_id){
            $this->dep_id=$dep_id;
        }

        $this->log("开始执行啦！".date('Y-m-d H:i:s'));
        if($type=='init'){
            $this->_init_all_data(2007);
        }elseif($type=='today'){//每天汇总当月数据
            $y = date('Y');
            $m = date('m');
            $this->_init_all_data($y,$m,1);
        }else{
            if($params['dep_id']){
                $this->run_day = strtotime($params['dep_id']);
            }else{
                $this->run_day = time();
            }

            $this->_each_end_month_execute();
        }
        $time_end = time();
        $this->log('(End Job--'.date('Y-m-d H:i:s').')'.($time_end-$time_start).'seconds');
    }
    private function _get_dimission_user($start,$end){
        $sql = "SELECT * FROM dep_user WHERE job_status=2 AND last_date>={$start} AND last_date<={$end} ";
        $data = $this->get_db_rows_assoc($sql,$this->write_db,array());

        if(!empty($data)){
            foreach ($data as $val){
                $depid = empty($val['department_id']) ? 0 : intval($val['department_id']);
                if(!$depid){continue;}//防止刚入职的人还没有部门
                if($val['user_type']!=1 && $val['user_type']!=2){
                    continue;//离职只统计试用和正式员工
                }
                if($val['leaving_type']==1){
                    $this->datalist[$depid]['active_num'] +=1;
                }elseif($val['leaving_type']==2){
                    $this->datalist[$depid]['passive_num'] +=1;
                }
            }
        }
        return $this->datalist;
    }
    /**
     * 取这段时间的在职人数作下月的是按部门汇总的期初人数，和这个月的pm
     * @param int $start
     * @param int $end
     * @return multitype:
     */
    private function _get_on_job_user($start,$end){
        $result=array();
        $start = 0;
        $limit = 100;
        while(true) {
            $sql="SELECT * FROM dep_user WHERE job_status=1 AND user_id >{$start} order by user_id asc limit {$limit}";
            $tmp = $this->get_db_rows($sql,$this->write_db,array());
            if(empty($tmp)) {
                $this->log("取完所有用户数据!");
                break;
            }
            $count = count($tmp);
            $start = $tmp[$count - 1]['user_id'];
            $result = array_merge($result,$tmp);
        }
        foreach ($result as $val){
            $depid = empty($val['department_id']) ? 0 : intval($val['department_id']);
            if(!$depid){continue;}//防止刚入职的人还没有部门
            //初始下部门数据
            if(empty($this->datalist[$depid])){
                $this->datalist[$depid] = $this->_dep_data_tpl();
            }
            //pm
            if($val['p_level']>0){
                $this->datalist[$depid]['on_p_num'] +=1;
            }
            if($val['m_level']>0){
                $this->datalist[$depid]['on_m_num'] +=1;
            }
            //当月入职的人
            if($val['enter_date'] >=$start && $val['enter_date']<=$end){
                $this->datalist[$depid]['enter_num'] +=1;
            }
            //下个月期初人数,也是当月的最后在职人数
            $this->datalist[$depid]['begin_num'] +=1;
        }
        return $result;
    }
    private function _dep_data_tpl(){
        return array(
                'function_id'=>0,
                'bu_id'=>0,
                'city_id'=>0,
                'department_id'=>0,
                'begin_num'=>0,
                'enter_num'=>0,
                'on_p_num'=>0,
                'on_m_num'=>0,
                'active_num'=>0,
                'passive_num'=>0,
        );
    }
    private function _get_all_department(){
        $sql="SELECT * FROM department WHERE 1";
        return $this->get_db_rows_assoc($sql,$this->write_db,array());
    }
    private function _insert_data($indata,$type=1){
        $sql = $this->_implode_field_value($indata);
        //先检测记录是否存在，存在就update
        $sqlx = "SELECT * FROM report_month where dateline={$indata['dateline']} AND department_id={$indata['department_id']}";
        $ckdata = $this->get_db_row($sqlx, $this->write_db, array());
        if(empty($ckdata['id'])){
            $type=1;
        }else{
            $type=0;
        }
        if($type==1){
            $sql = "INSERT INTO report_month SET $sql";
        }else{
            $sql = "UPDATE report_month SET $sql WHERE dateline={$indata['dateline']} AND department_id={$indata['department_id']}";
        }
        $this->execute($sql,array(),$this->write_db);
    }
    private function _implode_field_value($array, $glue = ',') {
        $sql = $comma = '';
        foreach ($array as $k => $v) {
            $sql .= $comma."`$k`='$v'";
            $comma = $glue;
        }
        return $sql;
    }

    /**
     * 公司是从2007 1月有数据
     * @param int $year
     * @param int $month
     */
    private function _init_all_data($year=2007,$j=1,$step=0){
        $all_user = $this->_get_all_user_data();
        $dep_list = $this->_get_all_department();

        if($year==2007){
            $j=1;
        }else{//这是为了每天跑当前月和上一个月
            $j-=1;
        }
        //得到所有有效的部门,有些部门有规划，但还没有人的，也需要写入report_month
        if($step==1){
            $has_ids = array();
            foreach($all_user as $val){
                $has_ids[$val['department_id']] =1;
            }
        }
        $today = date('Ym');
        //init department
        /*for ($i=$j;$i<=73;$i++){
            $unix_start = mktime(0,0,0,$i,1,$year);//20070111
            $unix_end = mktime(0,0,0,$i+1,0,$year);
            $ym = date('Ym',$unix_start);
            if($step==1){
                if($ym > $today){
                    continue;
                }
            }
            $start = date('Ymd',$unix_start);
            $end = date('Ymd',$unix_end);
            $next_unix_start = mktime(0,0,0,$i+1,1,$year);
            $next_start = date('Ymd',$next_unix_start);

            foreach($dep_list as $value){
                if($this->dep_id && $value['department_id'] !=$this->dep_id){
                    continue;
                }
                $indata = array(
                        'dateline'=>$ym,
                        'function_id'=>$value['function_id'],
                        'bu_id'=>$value['bu_id'],
                        'city_id'=>$value['city_id'],
                        'department_id'=>$value['department_id'],
                        'begin_num'=>0,
                        'enter_num'=>0,
                        'on_p_num'=>0,
                        'on_m_num'=>0,
                        'active_num'=>0,
                        'passive_num'=>0,
                );
                $this->_insert_data($indata,1);
            }
        }*/

        $data=array();
        for ($i=$j;$i<=73;$i++){//每个人都会从07开始统计是否在职
            $unix_start = mktime(0,0,0,$i,1,$year);//20070111
            $unix_end = mktime(0,0,0,$i+1,0,$year);
            $ym = date('Ym',$unix_start);
            if($step==1){
                if($ym > $today){
                    continue;
                }
            }
            if($step==1){//只在每天跑的时候使用,
                foreach($dep_list as $de_id=>$value){
                    if($value['is_deleted']==2){
                        continue;
                    }
                    if(empty($has_ids[$de_id])){
                        $this->_init_depart_data($ym,$value);
                    }
                }
            }
            $start = date('Ymd',$unix_start);
            $end = date('Ymd',$unix_end);
            $next_unix_start = mktime(0,0,0,$i+1,1,$year);
            $next_start = date('Ymd',$next_unix_start);

            foreach($all_user as $val){
                if($val['leaving_type']==3 || empty($val['enter_date'])){//未来报到都不算
                    continue;
                }
                $depid  = $val['department_id'];
                if(empty($depid)){
                    file_put_contents('/tmp/report_log.txt',$val['user_id']."not dep\n",FILE_APPEND);
                    continue;
                }
                if(empty($data[$depid][$ym])){
                    $data[$depid][$ym] = array(
                            'begin_num'=>0,
                            'enter_num'=>0,
                            'on_p_num'=>0,
                            'on_m_num'=>0,
                            'active_num'=>0,
                            'passive_num'=>0,
                    );
                }
                //按员工汇总部门初期人数
                if($val['enter_date'] >= $start && $val['enter_date'] <= $end){//入职人数
                    $data[$depid][$ym]['enter_num'] +=1;
                }
                //12 20130101
                if($val['enter_date'] < $start && (empty($val['last_date']) || $val['last_date'] >= $start)){//期初人数
                    $data[$depid][$ym]['begin_num'] +=1;
                    if($val['p_level']>0){
                        $data[$depid][$ym]['on_p_num'] +=1;
                    }
                    if($val['m_level']>0){
                        $data[$depid][$ym]['on_m_num'] +=1;
                    }
                }

                //试用和正式才算离职,但算在职人数
                if(!in_array($val['user_type'],array(1,2))){
                    continue;
                }
                if($val['last_date'] >= $start && $val['last_date'] <= $end && $val['leaving_type']){//离职人数
                    if($val['leaving_type']==1){
                        $data[$depid][$ym]['active_num'] +=1;
                    }elseif($val['leaving_type']==2){
                        $data[$depid][$ym]['passive_num'] +=1;
                    }
                }
            }
        }

        foreach ($data as $depid=>$val){
            foreach($val as $ym=> $value){
                $indata = array(
                        'dateline'=>$ym,
                        'function_id'=>$dep_list[$depid]['function_id'],
                        'bu_id'=>$dep_list[$depid]['bu_id'],
                        'city_id'=>$dep_list[$depid]['city_id'],
                        'department_id'=>$depid,
                        'begin_num'=>$value['begin_num'],
                        'enter_num'=>$value['enter_num'],
                        'on_p_num'=>$value['on_p_num'],
                        'on_m_num'=>$value['on_m_num'],
                        'active_num'=>$value['active_num'],
                        'passive_num'=>$value['passive_num'],
                        );
                $this->_insert_data($indata,1);
            }
        }
        $this->log("写入data");
        //print_r($data);
    }

    private function _init_depart_data($dateline,$value){
        $indata = array(
                'dateline'=>$dateline,
                'function_id'=>$value['function_id'],
                'bu_id'=>$value['bu_id'],
                'city_id'=>$value['city_id'],
                'department_id'=>$value['department_id'],
                'begin_num'=>0,
                'enter_num'=>0,
                'on_p_num'=>0,
                'on_m_num'=>0,
                'active_num'=>0,
                'passive_num'=>0,
        );
        $this->_insert_data($indata,1);
    }
    /**
     * 每月最后一天运行，统计当月入职和离职，再写入下月的期初人数
     */
    private function _each_end_month_execute(){
        $today=date('Ymd');
        $end_day = mktime(0,0,0,date('m')+1,0,date('Y'));

        if($today != date('Ymd',$end_day)){//当天是否为最后一天
            //$this->log("还没有到统计时间");exit;
        }
        $next_month = mktime(0,0,0,date('m')+1,1,date('Y'));
        $next_month=date('Ym',$next_month);
        $start_day = mktime(0,0,0,date('m'),1,date('Y'));
        /**
         * $start_day =20130101
         * $end_day = 20130131
        */
        $this->_get_on_job_user($start_day,$end_day);
        $this->_get_dimission_user($start_day,$end_day);

        $dep_list = $this->_get_all_department();
        $dep_ids =$dep_list;
        foreach ($this->datalist as $depid=>$val){
            unset($dep_ids[$depid]);
            //先写入下个月的记录
            $indata = array(
                    'dateline'=>$next_month,
                    'function_id'=>$dep_list[$depid]['function_id'],
                    'bu_id'=>$dep_list[$depid]['bu_id'],
                    'city_id'=>$dep_list[$depid]['city_id'],
                    'department_id'=>$depid,
                    'begin_num'=>$val['begin_num'],
            );
            $this->_insert_data($indata,1);
            $this->log($indata['dateline']."==".$depid."==".$dep_list[$depid]['department_name']."插入数据完成");
            //update当前月的记录
            unset($indata['begin_num']);//当前月不更新人数
            $indata['dateline'] = date('Ym');
            $indata['enter_num']=$val['enter_num'];
            $indata['on_p_num']=$val['on_p_num'];
            $indata['on_m_num']=$val['on_m_num'];
            $indata['active_num']=$val['active_num'];
            $indata['passive_num']=$val['passive_num'];
            $this->_insert_data($indata,2);
            $this->log($indata['dateline']."==".$depid."==".$dep_list[$depid]['department_name']."插入数据完成");
        }
        if(!empty($dep_ids)){//这里要取上个月的数据填充
            $s_ym = mktime(0,0,0,date('m'),0,date('Y'));
            $prev_month=date('Ym',$s_ym);
            foreach($dep_ids as $depid=>$value){
                $sql="SELECT * FROM report_month where department_id={$depid} AND dateline={$prev_month}";
                $hada=$this->get_db_row($sql, $this->write_db, array());
                if(!empty($hada['department_id'])){
                    $indata = array(
                            'dateline'=>date('Ym'),
                            'function_id'=>$value['function_id'],
                            'bu_id'=>$value['bu_id'],
                            'city_id'=>$value['city_id'],
                            'department_id'=>$depid,
                            'begin_num'=>$hada['begin_num'],
                            'enter_num'=>0,
                            'on_p_num'=>$hada['on_p_num'],
                            'on_m_num'=>$hada['on_m_num'],
                            'active_num'=>0,
                            'passive_num'=>0,
                    );
                    $this->_insert_data($indata,1);
                }
            }
        }
    }
    private function _get_all_user_data(){
        $result=array();
        $start = 0;
        $limit = 100;
        $where="";
        if($this->dep_id){
            $where = "AND department_id=".$this->dep_id;
        }
        while(true) {
            $sql="select * from dep_user where user_id >{$start} {$where} order by user_id asc limit {$limit}";
            $tmp = $this->get_db_rows($sql,$this->write_db,array());
            if(empty($tmp)) {
                $this->log("取完所有用户数据!");
                break;
            }
            $count = count($tmp);
            $start = $tmp[$count - 1]['user_id'];
            $result = array_merge($result,$tmp);
        }
        return $result;
    }
}